﻿using Microsoft.EntityFrameworkCore;
using System.Collections.ObjectModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization;

namespace EasyDDD.Domain
{
    [Index(nameof(IsDeleted))]
    [Index(nameof(TenantId))]
    public abstract class DomainEntity : IDomainEntity
    {
        [Comment("软删除")]
        [Required]
        [Column(Order = 1)]
        public virtual bool IsDeleted { get; protected set; } = false;

        [Comment("租户ID")]
        [Required]
        [Column(Order = 2)]
        public virtual Guid TenantId { get; set; }

        [Comment("行版本")]
        //[ConcurrencyCheck]
        public virtual Guid RowVersion { get; private set; } = default!;

        public abstract object[] GetKey();

        public virtual void Delete()
        {
            this.IsDeleted = true;
        }

        #region 事件
        [NotMapped]
        [JsonIgnore]
        private Collection<IDomainEvent> domainEvents = new Collection<IDomainEvent>();
        [NotMapped]
        [JsonIgnore]
        public IReadOnlyCollection<IDomainEvent> DomainEvents => domainEvents.AsReadOnly();


        public void AddDomainEvent(IDomainEvent item)
        {
            domainEvents.Add(item);
        }
        public void RemoveDomainEvent(IDomainEvent item)
        {
            domainEvents.Remove(item);
        }
        public void ClearDomainEvent()
        {
            domainEvents.Clear();
        }
        #endregion
    }


    public abstract class DomainEntity<TKey> : DomainEntity, IDomainEntity<TKey>
    {
        [Key]
        //[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        [Column(Order = 0)]
        [NotNull]
        [Comment("ID")]
        public virtual TKey Id { get; set; } = default!;

        //表示对象是否为全新创建的，未持久化的
        public bool IsTransiented()
        {
            return EqualityComparer<TKey>.Default.Equals(Id, default);
        }

        public virtual void Add()
        {
            if (!EqualityComparer<TKey>.Default.Equals(Id, default))
            {
                throw new InvalidOperationException($"该实体{this.GetType().Name}:{this.Id}已创建！");
            }
        }

        public override object[] GetKey()
        {
            return new object[] { Id };
        }

    }
}